<template>
  <div class="wrapper" ref="wrapper">
    <div class="content" ref="content"
      :style=" { height }">
      <div class="item"
        v-for="item in pool"
        :key="item.key"
        :style="{ transform: `translateY(${item.pos}px)` }">
        <p>{{ item.value }} - 视图渲染内容 - <span>额外节点</span>
        </p>
        </div>
    </div>
  </div>
</template>

<script>
import { throttle } from '@/utils'

export default {
  name: 'test',
  data () {
    return {
      scroll: null,
      ih: 100, // 每个 item 的高度
      count: 100, // item 的总数
      pool: [],
      poolSize: 20, // 自定义缓冲池
      sh: 0, // 当前滚动高度
      vh: 0, // wrapper (视图)高度
      translateY: 0
    }
  },
  computed: {
    startIndex () {
      return Math.ceil(this.sh / this.ih) - 1
    },
    endIndex () {
      return Math.ceil((this.sh + this.vh) / this.ih)
    },
    minPoolSize () {
      return Math.ceil(this.vh / this.ih) + 1
    },
    height () {
      return this.ih * this.count + 'px'
    },
    wrapper () {
      return this.$refs.wrapper
    }
  },
  mounted () {
    this.$nextTick(_ => {
      this.vh = this.wrapper.clientHeight
      this.calcPool()
      // console.log(this.pool)
      // console.log(this.vh, this.minPoolSize)
      this.initScroll()
    })
  },
  beforeDestroy () {
    this.wrapper.removeEventListener('scroll', throttle(this.scrollHandler, 30))
  },
  methods: {
    initScroll () {
      // 优化：使用节流
      this.wrapper.addEventListener('scroll', throttle(this.scrollHandler, 30))
    },
    scrollHandler (e) {
      const top = e.target.scrollTop
      // 优化：只有触发 startIndex 变化的滚动才会被计算
      if (Math.abs(top - this.sh) > this.ih) {
        this.translateY = e.target.scrollTop
        this.sh = e.target.scrollTop
        console.log(this.startIndex, this.endIndex)
        this.calcPool()
      }
    },
    dataSlice (start, end) {
      const ret = []
      for (let i = start; i < end; i++) {
        ret.push(i)
      }
      return ret
    },
    calcPool () {
      // 初始化
      if (!this.pool.length) {
        this.pool = this.dataSlice(this.startIndex, this.startIndex + this.poolSize + 1)
          .map((v, i) => ({
            pos: (this.startIndex + i) * this.ih,
            key: i + 1,
            value: v,
            index: v
          }))
      } else {
        // console.log(this.dataSlice(this.pool[0].index, this.startIndex))
        const delta = this.startIndex - this.pool[0].value - 1
        // console.log(this.pool.splice(0, delta))
        console.log(delta, this.endIndex - delta, this.endIndex)
        /* const data = this.dataSlice(this.endIndex - delta, this.endIndex + 1)
          .map((v, i) => ({
            // console.log(v)
            key: v.key,
            value: v.value + this.poolSize,
            pos: (v.value + this.poolSize) * this.ih
          }))

        // console.log(data)

        this.pool = this.pool.slice(delta).concat(data)
        console.log(this.pool) */
      }

      // 计算索引差集
      // const delta = this.startIndex - this.pool[0].index
      // console.log(this.pool[0].index, this.startIndex)
    }
  }
}
</script>

<style lang="scss" scoped>
.wrapper {
  box-sizing: border-box;
  position: relative;
  overflow: scroll;
  height: 100vh;
}

.content {
  position: relative;
  line-height: .9rem;
  .item {
    position: absolute;
    box-sizing: border-box;
    width: 100%;
    height: 1rem;
    background-color: #fff;
    border-bottom: 3px solid #ccc;
  }
}
</style>
